package com.youlian.cloud.common.config;

import com.dianping.cat.Cat;
import com.dianping.cat.message.Transaction;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.boot.diagnostics.FailureAnalysis;
import org.springframework.boot.diagnostics.FailureAnalysisReporter;
import org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

/**
 * 启动失败异常捕获
 *
 * @author : liukx
 * @create : 2018/9/17 11:17
 * @email : liukx@elab-plus.com
 */
@Component
public class CatAnalysisReporter implements FailureAnalysisReporter {

    private static final Log logger = LogFactory
            .getLog(LoggingFailureAnalysisReporter.class);

    @Override
    public void report(FailureAnalysis failureAnalysis) {
        Transaction t = Cat.newTransaction("START-FAIL", "CatAnalysisReporter");
        t.setStatus(failureAnalysis.getCause());
        if (logger.isDebugEnabled()) {
            logger.debug("Application failed to start due to an exception",
                    failureAnalysis.getCause());
        }
        if (logger.isErrorEnabled()) {
            logger.error(buildMessage(failureAnalysis), failureAnalysis.getCause());
        }
        t.complete();
        try {
            // 这里异常休眠是为了上面Cat的消息树能够构建之后发送到服务端.
            // 如果没有此步骤,可能CAT中还是捕获不到异常
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private String buildMessage(FailureAnalysis failureAnalysis) {
        StringBuilder builder = new StringBuilder();
        builder.append(String.format("%n%n"));
        builder.append(String.format("***************************%n"));
        builder.append(String.format("服务启动失败 - %n"));
        builder.append(String.format("***************************%n%n"));
        builder.append(String.format("Description:%n%n"));
        builder.append(String.format("%s%n", failureAnalysis.getDescription()));
        if (StringUtils.hasText(failureAnalysis.getAction())) {
            builder.append(String.format("%nAction:%n%n"));
            builder.append(String.format("%s%n", failureAnalysis.getAction()));
        }
        return builder.toString();
    }

}
